package com.rtsp.poe.rtsplive555;

import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceView;

import org.easydarwin.blogdemos.StringUtil;
import org.easydarwin.blogdemos.SyncVDecode;
import org.easydarwin.blogdemos.WaveOutWrapper;

public class PreviewPresenter {

    private final String TAG = "rtsp-PreviewPresenter";
    private RTSPClient rtspClient;
    private PreviewView mPreviewView;
    private Context context;
    private Handler mHandler = new Handler();

//    private SponVDecode decoder;
    private SyncVDecode decoder;
    private SurfaceView surfaceView;
    /** rtsp地址 */
    private String previewAddress = "";

    /** 是否开始了预览 */
    private boolean isStartPreview = false;
    private boolean isStreamForceTcp = false;

    private int previewWidth = 1920;
    private int previewHeight = 1080;
    private WaveOutWrapper waveOutWrapper;
    //音频解码器
    private AACDecoderUtil aacAudioUtil;

    private RTSPCallback callback = new RTSPCallback() {

        private byte[] mPpsSps;

        @Override
        public void onFrame(byte[] frameData, int len, int codecName) {
//            Log.d(TAG,"onFrame  codecName="+codecName+",len="+len+",data="+ StringUtil.printBuffer(frameData,0,24));
            if(codecName == 265){
                // 帧数据喂给解码器
                decoder.putData(frameData, len,codecName);
                return;
            }
            // 记录pps和sps
            if ((frameData[0] == 0 && frameData[1] == 0 && frameData[2] == 1 && (frameData[3] & 0x1f) == 7) || (frameData[0] == 0
                    && frameData[1] == 0 && frameData[2] == 0 && frameData[3] == 1 && (frameData[4] & 0x1f) == 7)) {
                mPpsSps = frameData;
            } else if ((frameData[0] == 0 && frameData[1] == 0 && frameData[2] == 1 && (frameData[3] & 0x1f) == 5)
                    || (frameData[0] == 0 && frameData[1] == 0 && frameData[2] == 0 && frameData[3] == 1
                    && (frameData[4] & 0x1f) == 5)) {
                // 在关键帧前面加上pps和sps数据
                byte[] data = new byte[mPpsSps.length + frameData.length];
                len = len + mPpsSps.length;
                System.arraycopy(mPpsSps, 0, data, 0, mPpsSps.length);
                System.arraycopy(frameData, 0, data, mPpsSps.length, frameData.length);
                frameData = data;
            }

            // 帧数据喂给解码器
            decoder.putData(frameData, len,codecName);
        }

        @Override
        public void onAudioData(byte[] data, int len, int codecType, int channels, int samplerate, int bitspersample, int bitrate, long pts) {
            Log.d(TAG,"onAudioData  data.length="+data.length+",codecType="+AUDIO_CODEC_TYPE.values()[codecType] +",channels="+channels+",samplerate="+samplerate+",bitspersample="+bitspersample+",bitrate="+bitrate+",pts="+pts);

            switch (AUDIO_CODEC_TYPE.values()[codecType]){
                case PCMA:
                    if(waveOutWrapper != null){
                        waveOutWrapper.WriteData(data,0, data.length);
                    } else {
                        waveOutWrapper = new WaveOutWrapper();
                        waveOutWrapper.Start(samplerate);
                    }
                    break;
                case PCMU:
                    break;
                case MPEG4_GENERIC:
                    Log.d(TAG,"onAudioData  len="+len+",data="+ StringUtil.printBuffer(data,0,24));
                    if(aacAudioUtil == null){
                        aacAudioUtil = new AACDecoderUtil(channels,samplerate);
                        aacAudioUtil.start();
                    } else {
                        aacAudioUtil.writeData(data, 0, len);
                    }
                    break;
                    default:
                        break;
            }

        }

        @Override
        public void onInfo(final String info) {
//            Log.d(TAG,"onInfo  info="+info);
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mPreviewView.showInfo(info);
                }
            });
        }

        @Override
        public void onResolution(int width, int height) {
            Log.d(TAG,"onResolution  width="+width+",height="+height);
        }
    };

    public PreviewPresenter(Context context, PreviewView pv) {
        this.context = context;
        mPreviewView = pv;
    }

    /** 设置渲染预览的SurfaceView */
    public void setSurfaceView(SurfaceView surfaceView) {
        this.surfaceView = surfaceView;
    }

    /** 开始预览 */
    public void startPreview() {
        if (isStartPreview) {
            Log.e(TAG, "startPreview: preview has started ");
            return;
        }

        if (surfaceView == null) {
            Log.e(TAG, "surfaceView == null");
            return;
        }
        if(decoder == null) {
            decoder = new SyncVDecode();
            try {
                decoder.init(surfaceView.getHolder().getSurface(), previewWidth, previewHeight);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        decoder.startDecodeThread();
        if(rtspClient == null){
            rtspClient = new RTSPClient();
            rtspClient.setOpenAudio(true);
        }
        rtspClient.setRTSPCallback(callback);
        // start() 阻塞，所以用子线程
        new Thread() {
            @Override
            public void run() {
                rtspClient.start(previewAddress,isStreamForceTcp);
            }
        }.start();

        isStartPreview = true;
    }

    /** 停止预览 */
    public void stopPreview() {
        if (rtspClient != null) {
            rtspClient.stop();
        }
        isStartPreview = false;
//        if (decoder != null) {
//            decoder.StopThread();
//            decoder = null;
//        }
//        surfaceView = null;
        if(waveOutWrapper != null){
            waveOutWrapper.Stop();
        }
    }

    public void setPreviewAddress(String address,boolean isStreamForceTcp) {
        this.previewAddress = address;
        this.isStreamForceTcp = isStreamForceTcp;
    }

    /** 是否正在播放预览 */
    public boolean isPlayingPreview() {
        return  isStartPreview;
    }
}
